﻿

using OpcRcw.Da;

using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Xml;

namespace OpcDaClient.Da
{

    public class Interop
    {
        internal static BrowseElement[] GetBrowseElements(
          ref IntPtr pInput,
          int count,
          bool deallocate)
        {
            BrowseElement[] browseElements = (BrowseElement[])null;
            if (pInput != IntPtr.Zero && count > 0)
            {
                browseElements = new BrowseElement[count];
                IntPtr pInput1 = pInput;
                for (int index = 0; index < count; ++index)
                {
                    browseElements[index] = Interop.GetBrowseElement(pInput1, deallocate);
                    pInput1 = (IntPtr)(pInput1.ToInt64() + (long)Marshal.SizeOf(typeof(OPCBROWSEELEMENT)));
                }
                if (deallocate)
                {
                    Marshal.FreeCoTaskMem(pInput);
                    pInput = IntPtr.Zero;
                }
            }
            return browseElements;
        }

        internal static IntPtr GetBrowseElements(BrowseElement[] input, bool propertiesRequested)
        {
            IntPtr browseElements = IntPtr.Zero;
            if (input != null && input.Length != 0)
            {
                browseElements = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCBROWSEELEMENT)) * input.Length);
                IntPtr ptr = browseElements;
                for (int index = 0; index < input.Length; ++index)
                {
                    Marshal.StructureToPtr((object)Interop.GetBrowseElement(input[index], propertiesRequested), ptr, false);
                    ptr = (IntPtr)(ptr.ToInt64() + (long)Marshal.SizeOf(typeof(OPCBROWSEELEMENT)));
                }
            }
            return browseElements;
        }

        internal static BrowseElement GetBrowseElement(IntPtr pInput, bool deallocate)
        {
            BrowseElement browseElement = (BrowseElement)null;
            if (pInput != IntPtr.Zero)
            {
                OPCBROWSEELEMENT structure = (OPCBROWSEELEMENT)Marshal.PtrToStructure(pInput, typeof(OPCBROWSEELEMENT));
                browseElement = new BrowseElement();
                browseElement.Name = structure.szName;
                browseElement.ItemPath = (string)null;
                browseElement.ItemName = structure.szItemID;
                browseElement.IsItem = (structure.dwFlagValue & 2) != 0;
                browseElement.HasChildren = (structure.dwFlagValue & 1) != 0;
                browseElement.Properties = Interop.GetItemProperties(ref structure.ItemProperties, deallocate);
                if (deallocate)
                    Marshal.DestroyStructure(pInput, typeof(OPCBROWSEELEMENT));
            }
            return browseElement;
        }

        internal static OPCBROWSEELEMENT GetBrowseElement(
          BrowseElement input,
          bool propertiesRequested)
        {
            OPCBROWSEELEMENT browseElement = new OPCBROWSEELEMENT();
            if (input != null)
            {
                browseElement.szName = input.Name;
                browseElement.szItemID = input.ItemName;
                browseElement.dwFlagValue = 0;
                browseElement.ItemProperties = Interop.GetItemProperties(input.Properties);
                if (input.IsItem)
                    browseElement.dwFlagValue |= 2;
                if (input.HasChildren)
                    browseElement.dwFlagValue |= 1;
            }
            return browseElement;
        }


        internal static ItemProperty[] GetItemProperties(
          ref OPCITEMPROPERTIES input,
          bool deallocate)
        {
            ItemProperty[] itemProperties = (ItemProperty[])null;
            if (input.dwNumProperties > 0)
            {
                itemProperties = new ItemProperty[input.dwNumProperties];
                IntPtr pInput = input.pItemProperties;
                for (int index = 0; index < itemProperties.Length; ++index)
                {
                    try
                    {
                        itemProperties[index] = Interop.GetItemProperty(pInput, deallocate);
                    }
                    catch (Exception ex)
                    {
                        itemProperties[index] = new ItemProperty();
                        itemProperties[index].Description = ex.Message;
                        itemProperties[index].ResultID = ResultID.E_FAIL;
                    }
                    pInput = (IntPtr)(pInput.ToInt64() + (long)Marshal.SizeOf(typeof(OPCITEMPROPERTY)));
                }
                if (deallocate)
                {
                    Marshal.FreeCoTaskMem(input.pItemProperties);
                    input.pItemProperties = IntPtr.Zero;
                }
            }
            return itemProperties;
        }

        internal static OPCITEMPROPERTIES GetItemProperties(ItemProperty[] input)
        {
            OPCITEMPROPERTIES itemProperties = new OPCITEMPROPERTIES();
            if (input != null && input.Length != 0)
            {
                itemProperties.hrErrorID = 0;
                itemProperties.dwReserved = 0;
                itemProperties.dwNumProperties = input.Length;
                itemProperties.pItemProperties = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMPROPERTY)) * input.Length);
                bool flag = false;
                IntPtr ptr = itemProperties.pItemProperties;
                for (int index = 0; index < input.Length; ++index)
                {
                    Marshal.StructureToPtr((object)Interop.GetItemProperty(input[index]), ptr, false);
                    ptr = (IntPtr)(ptr.ToInt64() + (long)Marshal.SizeOf(typeof(OPCITEMPROPERTY)));
                    if (input[index].ResultID.Failed())
                        flag = true;
                }
                if (flag)
                    itemProperties.hrErrorID = 1;
            }
            return itemProperties;
        }

        internal static ItemProperty GetItemProperty(IntPtr pInput, bool deallocate)
        {
            ItemProperty itemProperty = (ItemProperty)null;
            if (pInput != IntPtr.Zero)
            {
                OPCITEMPROPERTY structure = (OPCITEMPROPERTY)Marshal.PtrToStructure(pInput, typeof(OPCITEMPROPERTY));
                itemProperty = new ItemProperty()
                {
                    ID = Interop.GetPropertyID(structure.dwPropertyID),
                    Description = structure.szDescription,
                    DataType = Interop.GetType((VarEnum)structure.vtDataType),
                    ItemPath = (string)null,
                    ItemName = structure.szItemID
                };
                itemProperty.Value = Interop.UnmarshalPropertyValue(itemProperty.ID, structure.vValue);
                itemProperty.ResultID = Interop.GetResultID(structure.hrErrorID);
                if (structure.hrErrorID == -1073479674)
                    itemProperty.ResultID = new ResultID(ResultID.Da.E_WRITEONLY, -1073479674L);
                if (deallocate)
                    Marshal.DestroyStructure(pInput, typeof(OPCITEMPROPERTY));
            }
            return itemProperty;
        }
        internal static ResultID GetResultID(int input)
        {
            switch (input)
            {
                case -2147467262:
                    return new ResultID(ResultID.E_NOTSUPPORTED, (long)input);
                case -2147467259:
                    return new ResultID(ResultID.E_FAIL, (long)input);
                case -2147352571:
                    return new ResultID(ResultID.Da.E_BADTYPE, (long)input);
                case -2147352566:
                    return new ResultID(ResultID.Da.E_RANGE, (long)input);
                case -2147217401:
                    return new ResultID(ResultID.Hda.W_NOFILTER, (long)input);
                case -2147024882:
                    return new ResultID(ResultID.E_OUTOFMEMORY, (long)input);
                case -2147024809:
                    return new ResultID(ResultID.E_INVALIDARG, (long)input);
                case -1073479679:
                    return new ResultID(ResultID.Da.E_INVALIDHANDLE, (long)input);
                case -1073479676:
                    return new ResultID(ResultID.Da.E_BADTYPE, (long)input);
                case -1073479673:
                    return new ResultID(ResultID.Da.E_UNKNOWN_ITEM_NAME, (long)input);
                case -1073479672:
                    return new ResultID(ResultID.Da.E_INVALID_ITEM_NAME, (long)input);
                case -1073479671:
                    return new ResultID(ResultID.Da.E_INVALID_FILTER, (long)input);
                case -1073479670:
                    return new ResultID(ResultID.Da.E_UNKNOWN_ITEM_PATH, (long)input);
                case -1073479669:
                    return new ResultID(ResultID.Da.E_RANGE, (long)input);
                case -1073479165:
                    return new ResultID(ResultID.Da.E_INVALID_PID, (long)input);
                case -1073479164:
                    return new ResultID(ResultID.Ae.E_INVALIDTIME, (long)input);
                case -1073479163:
                    return new ResultID(ResultID.Ae.E_BUSY, (long)input);
                case -1073479162:
                    return new ResultID(ResultID.Ae.E_NOINFO, (long)input);
                case -1073478655:
                    return new ResultID(ResultID.Da.E_NO_ITEM_DEADBAND, (long)input);
                case -1073478654:
                    return new ResultID(ResultID.Da.E_NO_ITEM_BUFFERING, (long)input);
                case -1073478653:
                    return new ResultID(ResultID.Da.E_INVALIDCONTINUATIONPOINT, (long)input);
                case -1073478650:
                    return new ResultID(ResultID.Da.E_NO_WRITEQT, (long)input);
                case -1073478649:
                    return new ResultID(ResultID.Cpx.E_TYPE_CHANGED, (long)input);
                case -1073478648:
                    return new ResultID(ResultID.Cpx.E_FILTER_DUPLICATE, (long)input);
                case -1073478647:
                    return new ResultID(ResultID.Cpx.E_FILTER_INVALID, (long)input);
                case -1073478646:
                    return new ResultID(ResultID.Cpx.E_FILTER_ERROR, (long)input);
                case -1073477888:
                    return new ResultID(ResultID.Dx.E_PERSISTING, (long)input);
                case -1073477887:
                    return new ResultID(ResultID.Dx.E_NOITEMLIST, (long)input);
                case -1073477886:
                    return new ResultID(ResultID.Dx.E_VERSION_MISMATCH, (long)input);
                case -1073477885:
                    return new ResultID(ResultID.Dx.E_VERSION_MISMATCH, (long)input);
                case -1073477884:
                    return new ResultID(ResultID.Dx.E_UNKNOWN_ITEM_PATH, (long)input);
                case -1073477883:
                    return new ResultID(ResultID.Dx.E_UNKNOWN_ITEM_NAME, (long)input);
                case -1073477882:
                    return new ResultID(ResultID.Dx.E_INVALID_ITEM_PATH, (long)input);
                case -1073477881:
                    return new ResultID(ResultID.Dx.E_INVALID_ITEM_NAME, (long)input);
                case -1073477880:
                    return new ResultID(ResultID.Dx.E_INVALID_NAME, (long)input);
                case -1073477879:
                    return new ResultID(ResultID.Dx.E_DUPLICATE_NAME, (long)input);
                case -1073477878:
                    return new ResultID(ResultID.Dx.E_INVALID_BROWSE_PATH, (long)input);
                case -1073477877:
                    return new ResultID(ResultID.Dx.E_INVALID_SERVER_URL, (long)input);
                case -1073477876:
                    return new ResultID(ResultID.Dx.E_INVALID_SERVER_TYPE, (long)input);
                case -1073477875:
                    return new ResultID(ResultID.Dx.E_UNSUPPORTED_SERVER_TYPE, (long)input);
                case -1073477874:
                    return new ResultID(ResultID.Dx.E_CONNECTIONS_EXIST, (long)input);
                case -1073477873:
                    return new ResultID(ResultID.Dx.E_TOO_MANY_CONNECTIONS, (long)input);
                case -1073477872:
                    return new ResultID(ResultID.Dx.E_OVERRIDE_BADTYPE, (long)input);
                case -1073477871:
                    return new ResultID(ResultID.Dx.E_OVERRIDE_RANGE, (long)input);
                case -1073477870:
                    return new ResultID(ResultID.Dx.E_SUBSTITUTE_BADTYPE, (long)input);
                case -1073477869:
                    return new ResultID(ResultID.Dx.E_SUBSTITUTE_RANGE, (long)input);
                case -1073477868:
                    return new ResultID(ResultID.Dx.E_INVALID_TARGET_ITEM, (long)input);
                case -1073477867:
                    return new ResultID(ResultID.Dx.E_UNKNOWN_TARGET_ITEM, (long)input);
                case -1073477866:
                    return new ResultID(ResultID.Dx.E_TARGET_ALREADY_CONNECTED, (long)input);
                case -1073477865:
                    return new ResultID(ResultID.Dx.E_UNKNOWN_SERVER_NAME, (long)input);
                case -1073477864:
                    return new ResultID(ResultID.Dx.E_UNKNOWN_SOURCE_ITEM, (long)input);
                case -1073477863:
                    return new ResultID(ResultID.Dx.E_INVALID_SOURCE_ITEM, (long)input);
                case -1073477862:
                    return new ResultID(ResultID.Dx.E_INVALID_QUEUE_SIZE, (long)input);
                case -1073477861:
                    return new ResultID(ResultID.Dx.E_INVALID_DEADBAND, (long)input);
                case -1073477860:
                    return new ResultID(ResultID.Dx.E_INVALID_CONFIG_FILE, (long)input);
                case -1073477859:
                    return new ResultID(ResultID.Dx.E_PERSIST_FAILED, (long)input);
                case -1073477858:
                    return new ResultID(ResultID.Dx.E_TARGET_FAULT, (long)input);
                case -1073477857:
                    return new ResultID(ResultID.Dx.E_TARGET_NO_ACCESSS, (long)input);
                case -1073477856:
                    return new ResultID(ResultID.Dx.E_SOURCE_SERVER_FAULT, (long)input);
                case -1073477855:
                    return new ResultID(ResultID.Dx.E_SOURCE_SERVER_NO_ACCESSS, (long)input);
                case -1073477854:
                    return new ResultID(ResultID.Dx.E_SUBSCRIPTION_FAULT, (long)input);
                case -1073477853:
                    return new ResultID(ResultID.Dx.E_SOURCE_ITEM_BADRIGHTS, (long)input);
                case -1073477852:
                    return new ResultID(ResultID.Dx.E_SOURCE_ITEM_BAD_QUALITY, (long)input);
                case -1073477851:
                    return new ResultID(ResultID.Dx.E_SOURCE_ITEM_BADTYPE, (long)input);
                case -1073477850:
                    return new ResultID(ResultID.Dx.E_SOURCE_ITEM_RANGE, (long)input);
                case -1073477849:
                    return new ResultID(ResultID.Dx.E_SOURCE_SERVER_NOT_CONNECTED, (long)input);
                case -1073477848:
                    return new ResultID(ResultID.Dx.E_SOURCE_SERVER_TIMEOUT, (long)input);
                case -1073477847:
                    return new ResultID(ResultID.Dx.E_TARGET_ITEM_DISCONNECTED, (long)input);
                case -1073477846:
                    return new ResultID(ResultID.Dx.E_TARGET_NO_WRITES_ATTEMPTED, (long)input);
                case -1073477845:
                    return new ResultID(ResultID.Dx.E_TARGET_ITEM_BADTYPE, (long)input);
                case -1073477844:
                    return new ResultID(ResultID.Dx.E_TARGET_ITEM_RANGE, (long)input);
                case -1073475583:
                    return new ResultID(ResultID.Hda.E_MAXEXCEEDED, (long)input);
                case -1073475580:
                    return new ResultID(ResultID.Hda.E_INVALIDAGGREGATE, (long)input);
                case -1073475576:
                    return new ResultID(ResultID.Hda.E_UNKNOWNATTRID, (long)input);
                case -1073475575:
                    return new ResultID(ResultID.Hda.E_NOT_AVAIL, (long)input);
                case -1073475574:
                    return new ResultID(ResultID.Hda.E_INVALIDDATATYPE, (long)input);
                case -1073475573:
                    return new ResultID(ResultID.Hda.E_DATAEXISTS, (long)input);
                case -1073475572:
                    return new ResultID(ResultID.Hda.E_INVALIDATTRID, (long)input);
                case -1073475571:
                    return new ResultID(ResultID.Hda.E_NODATAEXISTS, (long)input);
                case 0:
                    return new ResultID(ResultID.S_OK, (long)input);
                case 262157:
                    return new ResultID(ResultID.Da.S_UNSUPPORTEDRATE, (long)input);
                case 262158:
                    return new ResultID(ResultID.Da.S_CLAMP, (long)input);
                case 262656:
                    return new ResultID(ResultID.Ae.S_ALREADYACKED, (long)input);
                case 262657:
                    return new ResultID(ResultID.Ae.S_INVALIDBUFFERTIME, (long)input);
                case 262658:
                    return new ResultID(ResultID.Ae.S_INVALIDMAXSIZE, (long)input);
                case 262659:
                    return new ResultID(ResultID.Ae.S_INVALIDKEEPALIVETIME, (long)input);
                case 263172:
                    return new ResultID(ResultID.Da.S_DATAQUEUEOVERFLOW, (long)input);
                case 263179:
                    return new ResultID(ResultID.Cpx.S_FILTER_NO_DATA, (long)input);
                case 264064:
                    return new ResultID(ResultID.Dx.S_TARGET_SUBSTITUTED, (long)input);
                case 264065:
                    return new ResultID(ResultID.Dx.S_TARGET_OVERRIDEN, (long)input);
                case 264066:
                    return new ResultID(ResultID.Dx.S_CLAMP, (long)input);
                case 1074008066:
                    return new ResultID(ResultID.Hda.S_NODATA, (long)input);
                case 1074008067:
                    return new ResultID(ResultID.Hda.S_MOREDATA, (long)input);
                case 1074008069:
                    return new ResultID(ResultID.Hda.S_CURRENTVALUE, (long)input);
                case 1074008070:
                    return new ResultID(ResultID.Hda.S_EXTRADATA, (long)input);
                case 1074008078:
                    return new ResultID(ResultID.Hda.S_INSERTED, (long)input);
                case 1074008079:
                    return new ResultID(ResultID.Hda.S_REPLACED, (long)input);
                default:
                    if ((input & 2147418112) == 65536)
                        return new ResultID(ResultID.E_NETWORK_ERROR, (long)input);
                    return input >= 0 ? new ResultID(ResultID.S_FALSE, (long)input) : new ResultID(ResultID.E_FAIL, (long)input);
            }
        }
        internal static VarEnum GetType(System.Type input)
        {
            if (input == (System.Type)null)
                return VarEnum.VT_EMPTY;
            if (input == typeof(sbyte))
                return VarEnum.VT_I1;
            if (input == typeof(byte))
                return VarEnum.VT_UI1;
            if (input == typeof(short))
                return VarEnum.VT_I2;
            if (input == typeof(ushort))
                return VarEnum.VT_UI2;
            if (input == typeof(int))
                return VarEnum.VT_I4;
            if (input == typeof(uint))
                return VarEnum.VT_UI4;
            if (input == typeof(long))
                return VarEnum.VT_I8;
            if (input == typeof(ulong))
                return VarEnum.VT_UI8;
            if (input == typeof(float))
                return VarEnum.VT_R4;
            if (input == typeof(double))
                return VarEnum.VT_R8;
            if (input == typeof(Decimal))
                return VarEnum.VT_CY;
            if (input == typeof(bool))
                return VarEnum.VT_BOOL;
            if (input == typeof(DateTime))
                return VarEnum.VT_DATE;
            if (input == typeof(string))
                return VarEnum.VT_BSTR;
            if (input == typeof(object))
                return VarEnum.VT_EMPTY;
            if (input == typeof(sbyte[]))
                return VarEnum.VT_I1 | VarEnum.VT_ARRAY;
            if (input == typeof(byte[]))
                return VarEnum.VT_UI1 | VarEnum.VT_ARRAY;
            if (input == typeof(short[]))
                return VarEnum.VT_I2 | VarEnum.VT_ARRAY;
            if (input == typeof(ushort[]))
                return VarEnum.VT_UI2 | VarEnum.VT_ARRAY;
            if (input == typeof(int[]))
                return VarEnum.VT_I4 | VarEnum.VT_ARRAY;
            if (input == typeof(uint[]))
                return VarEnum.VT_UI4 | VarEnum.VT_ARRAY;
            if (input == typeof(long[]))
                return VarEnum.VT_I8 | VarEnum.VT_ARRAY;
            if (input == typeof(ulong[]))
                return VarEnum.VT_UI8 | VarEnum.VT_ARRAY;
            if (input == typeof(float[]))
                return VarEnum.VT_R4 | VarEnum.VT_ARRAY;
            if (input == typeof(double[]))
                return VarEnum.VT_R8 | VarEnum.VT_ARRAY;
            if (input == typeof(Decimal[]))
                return VarEnum.VT_CY | VarEnum.VT_ARRAY;
            if (input == typeof(bool[]))
                return VarEnum.VT_BOOL | VarEnum.VT_ARRAY;
            if (input == typeof(DateTime[]))
                return VarEnum.VT_DATE | VarEnum.VT_ARRAY;
            if (input == typeof(string[]))
                return VarEnum.VT_BSTR | VarEnum.VT_ARRAY;
            if (input == typeof(object[]))
                return VarEnum.VT_VARIANT | VarEnum.VT_ARRAY;
            if (input == Type.ILLEGAL_TYPE)
                return (VarEnum)System.Enum.ToObject(typeof(VarEnum), (int)short.MaxValue);
            if (input == typeof(System.Type) || input == typeof(Quality))
                return VarEnum.VT_I2;
            return input == typeof(accessRights) || input == typeof(euType) ? VarEnum.VT_I4 : VarEnum.VT_EMPTY;
        }
        internal static int GetResultID(ResultID input)
        {
            if (input.Name != (XmlQualifiedName)null && input.Name.Namespace == "http://opcfoundation.org/DataAccess/")
            {
                if (input == ResultID.S_OK)
                    return 0;
                if (input == ResultID.E_FAIL)
                    return -2147467259;
                if (input == ResultID.E_INVALIDARG)
                    return -2147024809;
                if (input == ResultID.Da.E_BADTYPE)
                    return -1073479676;
                if (input == ResultID.Da.E_READONLY || input == ResultID.Da.E_WRITEONLY)
                    return -1073479674;
                if (input == ResultID.Da.E_RANGE)
                    return -1073479669;
                if (input == ResultID.E_OUTOFMEMORY)
                    return -2147024882;
                if (input == ResultID.E_NOTSUPPORTED)
                    return -2147467262;
                if (input == ResultID.Da.E_INVALIDHANDLE)
                    return -1073479679;
                if (input == ResultID.Da.E_UNKNOWN_ITEM_NAME)
                    return -1073479673;
                if (input == ResultID.Da.E_INVALID_ITEM_NAME || input == ResultID.Da.E_INVALID_ITEM_PATH)
                    return -1073479672;
                if (input == ResultID.Da.E_UNKNOWN_ITEM_PATH)
                    return -1073479670;
                if (input == ResultID.Da.E_INVALID_FILTER)
                    return -1073479671;
                if (input == ResultID.Da.S_UNSUPPORTEDRATE)
                    return 262157;
                if (input == ResultID.Da.S_CLAMP)
                    return 262158;
                if (input == ResultID.Da.E_INVALID_PID)
                    return -1073479165;
                if (input == ResultID.Da.E_NO_ITEM_DEADBAND)
                    return -1073478655;
                if (input == ResultID.Da.E_NO_ITEM_BUFFERING)
                    return -1073478654;
                if (input == ResultID.Da.E_NO_WRITEQT)
                    return -1073478650;
                if (input == ResultID.Da.E_INVALIDCONTINUATIONPOINT)
                    return -1073478653;
                if (input == ResultID.Da.S_DATAQUEUEOVERFLOW)
                    return 263172;
            }
            else if (input.Name != (XmlQualifiedName)null && input.Name.Namespace == "http://opcfoundation.org/ComplexData/")
            {
                if (input == ResultID.Cpx.E_TYPE_CHANGED)
                    return -1073478649;
                if (input == ResultID.Cpx.E_FILTER_DUPLICATE)
                    return -1073478648;
                if (input == ResultID.Cpx.E_FILTER_INVALID)
                    return -1073478647;
                if (input == ResultID.Cpx.E_FILTER_ERROR)
                    return -1073478646;
                if (input == ResultID.Cpx.S_FILTER_NO_DATA)
                    return 263179;
            }
            else if (input.Name != (XmlQualifiedName)null && input.Name.Namespace == "http://opcfoundation.org/HistoricalDataAccess/")
            {
                if (input == ResultID.Hda.E_MAXEXCEEDED)
                    return -1073475583;
                if (input == ResultID.Hda.S_NODATA)
                    return 1074008066;
                if (input == ResultID.Hda.S_MOREDATA)
                    return 1074008067;
                if (input == ResultID.Hda.E_INVALIDAGGREGATE)
                    return -1073475580;
                if (input == ResultID.Hda.S_CURRENTVALUE)
                    return 1074008069;
                if (input == ResultID.Hda.S_EXTRADATA)
                    return 1074008070;
                if (input == ResultID.Hda.E_UNKNOWNATTRID)
                    return -1073475576;
                if (input == ResultID.Hda.E_NOT_AVAIL)
                    return -1073475575;
                if (input == ResultID.Hda.E_INVALIDDATATYPE)
                    return -1073475574;
                if (input == ResultID.Hda.E_DATAEXISTS)
                    return -1073475573;
                if (input == ResultID.Hda.E_INVALIDATTRID)
                    return -1073475572;
                if (input == ResultID.Hda.E_NODATAEXISTS)
                    return -1073475571;
                if (input == ResultID.Hda.S_INSERTED)
                    return 1074008078;
                if (input == ResultID.Hda.S_REPLACED)
                    return 1074008079;
            }
            if (input.Name != (XmlQualifiedName)null && input.Name.Namespace == "http://opcfoundation.org/DataExchange/")
            {
                if (input == ResultID.Dx.E_PERSISTING)
                    return -1073477888;
                if (input == ResultID.Dx.E_NOITEMLIST)
                    return -1073477887;
                if (input == ResultID.Dx.E_SERVER_STATE || input == ResultID.Dx.E_VERSION_MISMATCH)
                    return -1073477885;
                if (input == ResultID.Dx.E_UNKNOWN_ITEM_PATH)
                    return -1073477884;
                if (input == ResultID.Dx.E_UNKNOWN_ITEM_NAME)
                    return -1073477883;
                if (input == ResultID.Dx.E_INVALID_ITEM_PATH)
                    return -1073477882;
                if (input == ResultID.Dx.E_INVALID_ITEM_NAME)
                    return -1073477881;
                if (input == ResultID.Dx.E_INVALID_NAME)
                    return -1073477880;
                if (input == ResultID.Dx.E_DUPLICATE_NAME)
                    return -1073477879;
                if (input == ResultID.Dx.E_INVALID_BROWSE_PATH)
                    return -1073477878;
                if (input == ResultID.Dx.E_INVALID_SERVER_URL)
                    return -1073477877;
                if (input == ResultID.Dx.E_INVALID_SERVER_TYPE)
                    return -1073477876;
                if (input == ResultID.Dx.E_UNSUPPORTED_SERVER_TYPE)
                    return -1073477875;
                if (input == ResultID.Dx.E_CONNECTIONS_EXIST)
                    return -1073477874;
                if (input == ResultID.Dx.E_TOO_MANY_CONNECTIONS)
                    return -1073477873;
                if (input == ResultID.Dx.E_OVERRIDE_BADTYPE)
                    return -1073477872;
                if (input == ResultID.Dx.E_OVERRIDE_RANGE)
                    return -1073477871;
                if (input == ResultID.Dx.E_SUBSTITUTE_BADTYPE)
                    return -1073477870;
                if (input == ResultID.Dx.E_SUBSTITUTE_RANGE)
                    return -1073477869;
                if (input == ResultID.Dx.E_INVALID_TARGET_ITEM)
                    return -1073477868;
                if (input == ResultID.Dx.E_UNKNOWN_TARGET_ITEM)
                    return -1073477867;
                if (input == ResultID.Dx.E_TARGET_ALREADY_CONNECTED)
                    return -1073477866;
                if (input == ResultID.Dx.E_UNKNOWN_SERVER_NAME)
                    return -1073477865;
                if (input == ResultID.Dx.E_UNKNOWN_SOURCE_ITEM)
                    return -1073477864;
                if (input == ResultID.Dx.E_INVALID_SOURCE_ITEM)
                    return -1073477863;
                if (input == ResultID.Dx.E_INVALID_QUEUE_SIZE)
                    return -1073477862;
                if (input == ResultID.Dx.E_INVALID_DEADBAND)
                    return -1073477861;
                if (input == ResultID.Dx.E_INVALID_CONFIG_FILE)
                    return -1073477860;
                if (input == ResultID.Dx.E_PERSIST_FAILED)
                    return -1073477859;
                if (input == ResultID.Dx.E_TARGET_FAULT)
                    return -1073477858;
                if (input == ResultID.Dx.E_TARGET_NO_ACCESSS)
                    return -1073477857;
                if (input == ResultID.Dx.E_SOURCE_SERVER_FAULT)
                    return -1073477856;
                if (input == ResultID.Dx.E_SOURCE_SERVER_NO_ACCESSS)
                    return -1073477855;
                if (input == ResultID.Dx.E_SUBSCRIPTION_FAULT)
                    return -1073477854;
                if (input == ResultID.Dx.E_SOURCE_ITEM_BADRIGHTS)
                    return -1073477853;
                if (input == ResultID.Dx.E_SOURCE_ITEM_BAD_QUALITY)
                    return -1073477852;
                if (input == ResultID.Dx.E_SOURCE_ITEM_BADTYPE)
                    return -1073477851;
                if (input == ResultID.Dx.E_SOURCE_ITEM_RANGE)
                    return -1073477850;
                if (input == ResultID.Dx.E_SOURCE_SERVER_NOT_CONNECTED)
                    return -1073477849;
                if (input == ResultID.Dx.E_SOURCE_SERVER_TIMEOUT)
                    return -1073477848;
                if (input == ResultID.Dx.E_TARGET_ITEM_DISCONNECTED)
                    return -1073477847;
                if (input == ResultID.Dx.E_TARGET_NO_WRITES_ATTEMPTED)
                    return -1073477846;
                if (input == ResultID.Dx.E_TARGET_ITEM_BADTYPE)
                    return -1073477845;
                if (input == ResultID.Dx.E_TARGET_ITEM_RANGE)
                    return -1073477844;
                if (input == ResultID.Dx.S_TARGET_SUBSTITUTED)
                    return 264064;
                if (input == ResultID.Dx.S_TARGET_OVERRIDEN)
                    return 264065;
                if (input == ResultID.Dx.S_CLAMP)
                    return 264066;
            }
            else if (input.Code == -1)
                return input.Succeeded() ? 1 : -2147467259;
            return input.Code;
        }

        internal static OPCITEMPROPERTY GetItemProperty(ItemProperty input)
        {
            OPCITEMPROPERTY itemProperty = new OPCITEMPROPERTY();
            if (input != null)
            {
                itemProperty.dwPropertyID = input.ID.Code;
                itemProperty.szDescription = input.Description;
                itemProperty.vtDataType = (short)Interop.GetType(input.DataType);
                itemProperty.vValue = Interop.MarshalPropertyValue(input.ID, input.Value);
                itemProperty.wReserved = (short)0;
                itemProperty.hrErrorID = Interop.GetResultID(input.ResultID);
                PropertyDescription propertyDescription = PropertyDescription.Find(input.ID);
                if (propertyDescription != null)
                    itemProperty.vtDataType = (short)Interop.GetType(propertyDescription.Type);
                if (input.ResultID == ResultID.Da.E_WRITEONLY)
                    itemProperty.hrErrorID = -1073479674;
            }
            return itemProperty;
        }

        public static PropertyID GetPropertyID(int input)
        {
            foreach (FieldInfo field in typeof(Property).GetFields(BindingFlags.Static | BindingFlags.Public))
            {
                PropertyID propertyId = (PropertyID)field.GetValue((object)typeof(PropertyID));
                if (input == propertyId.Code)
                    return propertyId;
            }
            return new PropertyID(input);
        }

        internal static System.Type GetType(VarEnum input)
        {
            switch (input)
            {
                case VarEnum.VT_EMPTY:
                    return (System.Type)null;
                case VarEnum.VT_I2:
                    return typeof(short);
                case VarEnum.VT_I4:
                    return typeof(int);
                case VarEnum.VT_R4:
                    return typeof(float);
                case VarEnum.VT_R8:
                    return typeof(double);
                case VarEnum.VT_CY:
                    return typeof(Decimal);
                case VarEnum.VT_DATE:
                    return typeof(DateTime);
                case VarEnum.VT_BSTR:
                    return typeof(string);
                case VarEnum.VT_BOOL:
                    return typeof(bool);
                case VarEnum.VT_I1:
                    return typeof(sbyte);
                case VarEnum.VT_UI1:
                    return typeof(byte);
                case VarEnum.VT_UI2:
                    return typeof(ushort);
                case VarEnum.VT_UI4:
                    return typeof(uint);
                case VarEnum.VT_I8:
                    return typeof(long);
                case VarEnum.VT_UI8:
                    return typeof(ulong);
                case VarEnum.VT_I2 | VarEnum.VT_ARRAY:
                    return typeof(short[]);
                case VarEnum.VT_I4 | VarEnum.VT_ARRAY:
                    return typeof(int[]);
                case VarEnum.VT_R4 | VarEnum.VT_ARRAY:
                    return typeof(float[]);
                case VarEnum.VT_R8 | VarEnum.VT_ARRAY:
                    return typeof(double[]);
                case VarEnum.VT_CY | VarEnum.VT_ARRAY:
                    return typeof(Decimal[]);
                case VarEnum.VT_DATE | VarEnum.VT_ARRAY:
                    return typeof(DateTime[]);
                case VarEnum.VT_BSTR | VarEnum.VT_ARRAY:
                    return typeof(string[]);
                case VarEnum.VT_BOOL | VarEnum.VT_ARRAY:
                    return typeof(bool[]);
                case VarEnum.VT_VARIANT | VarEnum.VT_ARRAY:
                    return typeof(object[]);
                case VarEnum.VT_I1 | VarEnum.VT_ARRAY:
                    return typeof(sbyte[]);
                case VarEnum.VT_UI1 | VarEnum.VT_ARRAY:
                    return typeof(byte[]);
                case VarEnum.VT_UI2 | VarEnum.VT_ARRAY:
                    return typeof(ushort[]);
                case VarEnum.VT_UI4 | VarEnum.VT_ARRAY:
                    return typeof(uint[]);
                case VarEnum.VT_I8 | VarEnum.VT_ARRAY:
                    return typeof(long[]);
                case VarEnum.VT_UI8 | VarEnum.VT_ARRAY:
                    return typeof(ulong[]);
                default:
                    return Type.ILLEGAL_TYPE;
            }
        }
        internal static int[] GetPropertyIDs(PropertyID[] propertyIDs)
        {
            ArrayList arrayList = new ArrayList();
            if (propertyIDs != null)
            {
                foreach (PropertyID propertyId in propertyIDs)
                    arrayList.Add((object)propertyId.Code);
            }
            return (int[])arrayList.ToArray(typeof(int));
        }
        internal static object UnmarshalPropertyValue(PropertyID propertyID, object input)
        {
            if (input == null)
                return (object)null;
            try
            {
                if (propertyID == Property.DATATYPE)
                    return (object)Interop.GetType((VarEnum)System.Convert.ToUInt16(input));
                if (propertyID == Property.ACCESSRIGHTS)
                {
                    switch (System.Convert.ToInt32(input))
                    {
                        case 1:
                            return (object)accessRights.readable;
                        case 2:
                            return (object)accessRights.writable;
                        case 3:
                            return (object)accessRights.readWritable;
                        default:
                            return (object)null;
                    }
                }
                else if (propertyID == Property.EUTYPE)
                {
                    switch ((OPCEUTYPE)input)
                    {
                        case OPCEUTYPE.OPC_NOENUM:
                            return (object)euType.noEnum;
                        case OPCEUTYPE.OPC_ANALOG:
                            return (object)euType.analog;
                        case OPCEUTYPE.OPC_ENUMERATED:
                            return (object)euType.enumerated;
                        default:
                            return (object)null;
                    }
                }
                else
                {
                    if (propertyID == Property.QUALITY)
                        return (object)new Quality(System.Convert.ToInt16(input));
                    if (propertyID == Property.TIMESTAMP)
                    {
                        if (input.GetType() == typeof(DateTime))
                        {
                            DateTime dateTime = (DateTime)input;
                            return dateTime != DateTime.MinValue ? (object)dateTime.ToLocalTime() : (object)dateTime;
                        }
                    }
                }
            }
            catch
            {
            }
            return input;
        }

        internal static object MarshalPropertyValue(PropertyID propertyID, object input)
        {
            if (input == null)
                return (object)null;
            try
            {
                if (propertyID == Property.DATATYPE)
                    return (object)(short)Interop.GetType((System.Type)input);
                if (propertyID == Property.ACCESSRIGHTS)
                {
                    switch ((accessRights)input)
                    {
                        case accessRights.readable:
                            return (object)1;
                        case accessRights.writable:
                            return (object)2;
                        case accessRights.readWritable:
                            return (object)3;
                        default:
                            return (object)null;
                    }
                }
                else if (propertyID == Property.EUTYPE)
                {
                    switch ((euType)input)
                    {
                        case euType.noEnum:
                            return (object)OPCEUTYPE.OPC_NOENUM;
                        case euType.analog:
                            return (object)OPCEUTYPE.OPC_ANALOG;
                        case euType.enumerated:
                            return (object)OPCEUTYPE.OPC_ENUMERATED;
                        default:
                            return (object)null;
                    }
                }
                else
                {
                    if (propertyID == Property.QUALITY)
                        return (object)((Quality)input).GetCode();
                    if (propertyID == Property.TIMESTAMP)
                    {
                        if (input.GetType() == typeof(DateTime))
                        {
                            DateTime dateTime = (DateTime)input;
                            return dateTime != DateTime.MinValue ? (object)dateTime.ToUniversalTime() : (object)dateTime;
                        }
                    }
                }
            }
            catch
            {
            }
            return input;
        }

    }
}
